//
/*   Macros and Utility functions for Matrix * Vector operation program
*    Copyright (C) 2009 Goffredo Marocchi
*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License along
*    with this program; if not, write to the Free Software Foundation, Inc.,
*    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef MATTEST_HELPER_H
#define MATTEST_HELPER_H

#include "cublas.h"
#include "host_defines.h"
#include "builtin_types.h"

//////////////////////////////////////////////////////////////////////////////
// General helper functions													   //
//////////////////////////////////////////////////////////////////////////////

extern "C" void init_host_data_ (float* matA, float* vecB, float* h_C_CPU);
extern "C" float execute_test_cpu_ ( float* matA, float* vecB, float* h_C_CPU);
void mat_vec ( float * a, const int R, const int C, float * b, float * c);
bool vectorEQ (float*, float*, const int);
extern "C" void vector_eq_test_ (float*, float*, const int);

float RandFloat(float low, float high);

void malloc_MatrixFPv1 ( float ***, const int, const int);
void malloc_MatrixFPv2 ( float *, const int, const int);
void printVec (float* v, const int EL);
void printMat (float* m, const int R, const int C);

void start_timer (unsigned int* t);
void stop_timer (unsigned int t, float* t_ms);

extern "C" void gpu_print_free_memory_ ();
extern "C" void gpu_init_ ();

inline void __IGGSSafeMalloc( void *pointer, const char *file, const int line )
{
    do {
        if( !(pointer)) {
            fprintf(stderr, "malloc failure in file <%s>, line %i\n",
                    file, line);
            exit(-1);
        }
    } while (0);
}


//////////////////////////////////////////////////////////////////////////////
// CUBLAS helper functions													   //
//////////////////////////////////////////////////////////////////////////////

void CUBLAS_Allocate_GPU_memory (float* &d_ptr, const int n_elem);

void CUBLAS_Free_GPU_memory (float * d_ptr);

void CUBLAS_Write_to_GPU (float * &d_ptr, float *h_ptr, const int n_elem);

void CUBLAS_Read_from_GPU (float *h_ptr,  float * &d_ptr, const int data_size);

void CUBLAS_check_error ();

void CUBLAS_Init ();

//////////////////////////////////////////////////////////////////////////////
// CUDA helper functions													   	   //
//////////////////////////////////////////////////////////////////////////////

void Allocate_GPU_memory (float * &d_ptr, const int data_size) ;
void Free_GPU_memory (float * d_ptr);

void Write_to_GPU (float * &d_ptr, float *h_ptr, const int data_size) ;
void Read_from_GPU (float *h_ptr,  float * &d_ptr, const int data_size);
void BindTex1D_rmetFP (size_t *offset, texture <float, 1, cudaReadModeElementType> &texref, const void *devPtr) ;
void UnbindTex1D_rmetFP (texture <float, 1, cudaReadModeElementType> &texref) ;


#endif
